package main

/**
* @author aFun
* @data 2025/4/10 01:03
* @email: afunaaa222@163.com / 1030935903
* @address: Guangdong University of Technology, China
 */

import (
	"camp_lucky_draw/entity"
	"camp_lucky_draw/server"
	"camp_lucky_draw/server/data"
	"camp_lucky_draw/server/server_service"
	"camp_lucky_draw/transfer"
	"fmt"
	"github.com/shirou/gopsutil/v3/cpu"
	"github.com/shirou/gopsutil/v3/mem"
	"io"
	"net"
	"runtime/debug"
	"sync"
	"time"
)

type Processor struct {
	Conn net.Conn
}

// 客户端连接池
var userProcessPool = sync.Pool{
	New: func() interface{} {
		return &server_service.UserProcess{}
	},
}

func withUserProcess(conn net.Conn, handler func(up *server_service.UserProcess) error) error {
	up := userProcessPool.Get().(*server_service.UserProcess)
	up.Conn = conn
	defer func() {
		up.Conn = nil
		userProcessPool.Put(up)
	}()
	return handler(up)
}

func (this *Processor) serverProcessMes(mes *entity.Msg) (err error) {
	// 根据不同协议调用不同方法
	switch mes.Code {
	case 10001:
		// 进入游戏世界协议
		err = withUserProcess(this.Conn, func(up *server_service.UserProcess) error {
			return up.Enter_world(mes)
		})
	case 27100:
		// 请求个人信息协议
		err = withUserProcess(this.Conn, func(up *server_service.UserProcess) error {
			return up.Self_lucky_draw_data(mes)
		})
	case 27101:
		// 请求层奖励信息协议
		err = withUserProcess(this.Conn, func(up *server_service.UserProcess) error {
			return up.Floor_lucky_draw_data(mes)
		})
	case 27102:
		// 请求累计奖励信息协议
		err = withUserProcess(this.Conn, func(up *server_service.UserProcess) error {
			return up.Cumulative_lucky_draw_data(mes)
		})
	case 27103:
		err = withUserProcess(this.Conn, func(up *server_service.UserProcess) error {
			return up.Draw(mes)
		})
	case 27104:
		err = withUserProcess(this.Conn, func(up *server_service.UserProcess) error {
			return up.Gain_floor_rewards(mes)
		})
	case 27105:
		err = withUserProcess(this.Conn, func(up *server_service.UserProcess) error {
			return up.Gain_cumulative_rewards(mes)
		})
	case 10002:
		err = withUserProcess(this.Conn, func(up *server_service.UserProcess) error {
			err2 := up.Disconnect(mes)
			if err2 != nil {
				return err2
			} else {
				return nil
			}
		})
	}

	return err
}

func (this *Processor) process() (err error) {
	for {
		// 循环读取客户端发送的消息
		tf := &transfer.Transfer{
			Conn: this.Conn,
		}
		mes, err := tf.ReadPkg()
		if err != nil {
			if err == io.EOF {
				fmt.Println("client close.")
				return err
			} else {
				fmt.Println("", err)
				return err
			}
		}
		//fmt.Println("mes=", mes)
		err = this.serverProcessMes(mes)
		if err != nil {
			fmt.Println("serverProcessMes error:", err)
			return err
		}
	}
}

func init() {
	server.InnitOnlineUserMgr()
	server.Init_config()
	server.InitMYSQL()
	server.InitRedis()
	server.InitRabbitMQ()
	server.Init_campaign_data()
	server.Init_camp_lucky_draw_data()
	data.Init_data()
	go server.ListenRedisExpiredEvents() // 启动监听 Redis 过期事件
	go server.ConsumeRankingUpdates()    // 启动消耗榜监听协程
	go server.ConsumeNotifyingDelete()   // 启动redis过期键到点后推送至客户端致使其缓存失效的队列
	go server.ConsumeRewards()           // 启动异步增量更新
}

var (
	cpuSamples []float64
	memSamples []float64
	mu         sync.Mutex
)

func recordSystemUsage(interval time.Duration, duration time.Duration) {
	ticker := time.NewTicker(interval)
	defer ticker.Stop()

	timeout := time.After(duration)

	for {
		select {
		case <-timeout:
			// 打印平均值后退出
			printAverages()
			return
		case <-ticker.C:
			cpuPercent, _ := cpu.Percent(0, false)
			memStat, _ := mem.VirtualMemory()

			mu.Lock()
			if len(cpuPercent) > 0 {
				cpuSamples = append(cpuSamples, cpuPercent[0])
			}
			memSamples = append(memSamples, memStat.UsedPercent)
			mu.Unlock()
		}
	}
}

func printAverages() {
	mu.Lock()
	defer mu.Unlock()

	var cpuSum, memSum float64
	for _, v := range cpuSamples {
		cpuSum += v
	}
	for _, v := range memSamples {
		memSum += v
	}
	cpuAvg := cpuSum / float64(len(cpuSamples))
	memAvg := memSum / float64(len(memSamples))

	fmt.Printf("\n=== 资源使用均值 ===\n")
	fmt.Printf("平均 CPU 使用率: %.2f%%\n", cpuAvg)
	fmt.Printf("平均 内存使用率: %.2f%%\n", memAvg)
}

func main() {
	listen, err := net.Listen("tcp", "0.0.0.0:8889")
	if err != nil {
		panic(err)
	}
	defer server.DB.Close()
	go recordSystemUsage(5*time.Second, 10*time.Minute)
	for {
		fmt.Println("server running...")
		conn, err := listen.Accept()
		if err != nil {
			fmt.Println("accept error:", err)
			return
		}
		go run(conn)
	}

}

func run(conn net.Conn) {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("Recovered from panic:%v\n", r)
			debug.PrintStack()
		}
		err := conn.Close()
		if err != nil {
			fmt.Println("close conn error:", err)
		}
		fmt.Println("close conn success")
	}()

	processor := &Processor{conn}
	err := processor.process()
	if err != nil {
		fmt.Println("serverProcessPkg err:", err)
		if role, ok := server.OnlineUserMgr.OnlineUsers[conn]; ok {
			// 异常断开的情况
			// 防止重复删除或访问空值
			fmt.Println("Exception disconnect role:", role.ID)
			server.OnlineUserMgr.Mutex.Lock()
			delete(server.OnlineUserMgr.OnlineUsers, conn)
			delete(server.OnlineUserMgr.OnlineIdConn, role.ID)
			server.OnlineUserMgr.Mutex.Unlock()
		} else {
			fmt.Println("Connection already removed from OnlineUserMgr.")
		}
	}
}
